home *** CD-ROM | disk | FTP | other *** search
Text File | 1999-11-29 | 21.7 KB | 811 lines | [TEXT/ALFA] |
- ## -*-Tcl-*-
- # ###################################################################
- #
- # FILE: "shellMode.tcl"
- # last update: 29/11/1999 {12:58:18 pm}
- # Author: Vince Darley, Pete Keleher
- # E-mail: <vince@santafe.edu>
- # mail: Division of Engineering and Applied Sciences, Harvard University
- # Oxford Street, Cambridge MA 02138, USA
- # www: <http://www.santafe.edu/~vince/>
- #
- # Some Copyright (c) 1997-1998 Vince Darley, all rights reserved
- # Some copyright Pete Keleher.
- #
- # Description:
- #
- # General purpose shell routines for Alpha. Two and a half shells
- # are provided by default: the Alpha Tcl shell, the MPW toolserver
- # shell and half of the comet shell (whatever that is).
- #
- # A separate package 'remotetclshell' allows Alpha to act as a console
- # for a separately running Wish.
- # ###################################################################
- ##
-
- alpha::mode Shel 1.8.0 dummyShel [list {"*tcl sh*"}] tclMenu {
- addMode MPW {} [list "*Toolserver shell*"] {}
- # we use our own version since Alpha doesn't quite change mode
- # to Shel correctly (not sure what it does wrong).
- catch {rename shell {}}
- # we do this ourselves. this way we don't need a special hack
- # in 'openHook'
- catch {rename toolserverShell {}}
- }
-
- set Shel::startPrompt "«"
- set Shel::endPrompt "»"
-
- newPref v wordBreak {(\$)?[a-zA-Z0-9_.]+} Shel
- newPref f wordWrap {0} Shel
- newPref f perlCallUnixLike {0} Shel
- newPref v wordBreakPreface "\[^a-zA-Z0-9_\\$${Shel::endPrompt}\]" Shel
- newPref f autoMark 0 Shel
- newPref f tcl_interactive 1 Shel
-
- set invisibleModeVars(tcl_interactive) 1
- set Shel::endPara "^${Shel::startPrompt}.*$"
- set Shel::startPara "^${Shel::startPrompt}.*$"
- regModeKeywords -m ${Shel::startPrompt} Shel {}
-
- ensureset Shel::histnum 0
-
- Bind '\r' Shel::carriageReturn "Shel"
- Bind '\r' Shel::carriageReturn "MPW"
- Bind '\t' bind::Completion Shel
-
- Bind up <z> Shel::prevHist Shel
- Bind down <z> Shel::nextHist Shel
-
- Bind 'a' <z> Shel::Bol Shel
- Bind up Shel::up Shel
- Bind down Shel::down Shel
-
- Bind 'u' <z> Shel::killLine Shel
-
- proc dummyShel {} {}
-
- ensureset otherDirs {}
-
- proc Shel::OptionTitlebar {} {
- regsub -all "\n *" [history] "\} \{" h
- set h "\{[string trim $h]\}"
- }
-
- proc Shel::OptionTitlebarSelect {item} {
- insertText [string range $item [expr 2+[string first " " $item]] end]
- Shel::carriageReturn
- }
-
- proc Shel::DblClick {args} { eval Tcl::DblClick $args }
-
- ##
- # -------------------------------------------------------------------------
- #
- # "Shel::carriageReturn" --
- #
- # Rewritten to avoid need for global _text _return variables
- # -------------------------------------------------------------------------
- ##
- proc Shel::carriageReturn {} {
- global mode histnum Shel::Type Shel::endPrompt
- set pos [getPos]
-
- if {![catch {regexp {∞} [getText $pos [nextLineStart $pos]]} res] && $res} {
- gotoMatch; return;
- }
- set ind [string first ${Shel::endPrompt} [getText [lineStart $pos] $pos]]
- if {$ind < 0} {
- insertText "\r"
- return
- }
- endOfLine
- set fileName [win::CurrentTail]
- set type [set Shel::Type($fileName)]
- # sort out where we're going to put the answer
- set t [getText [pos::math [lineStart $pos] + [expr $ind+2]] [getPos]]
-
- if {[pos::compare [getPos] != [maxPos]]} {
- goto [set pos [maxPos]]
- set ind [string first ${Shel::endPrompt} [getText [lineStart $pos] $pos]]
- if {$ind < 0} {
- insertText "\r" [${type}::Prompt]
- } else {
- set ind [pos::math [lineStart $pos] + [expr $ind +2]]
- if {$ind != $pos} {
- deleteText $ind $pos
- }
- }
- insertText -w $fileName $t
- }
- # carry out the action
- insertText -w $fileName "\r"
- set r [${type}::evaluate $t]
- insertText -w $fileName $r
- if {$r != ""} {
- insertText -w $fileName "\r"
- }
- insertText -w $fileName [${type}::Prompt]
- }
-
- proc Shel::start {type {title ""} {startuptext ""}} {
- if {$title != ""} {
- if {[lsearch -exact [winNames] $title] != -1} {
- bringToFront $title
- return
- }
- new -n $title -m Shel -shell 1 -text $startuptext
- }
- global Shel::Type
- set c [win::Current]
- set Shel::Type($c) $type
- insertText -w $c [${type}::Prompt]
- }
-
- # ◊◊◊◊ Alpha shell routines ◊◊◊◊ #
-
- proc tclLog {args} {
- catch {eval insertText -w [list "*tcl shell*"] $args}
- }
-
- proc shell {} {
- Shel::start "Alpha" "*tcl shell*" "Welcome to Alpha's Tcl shell.\r"
- }
-
- namespace eval Alpha {}
-
- proc Alpha::evaluate {t} {
- global errorInfo Shel::histnum
- global Shel::AlphaAlias
- history add $t
- set msg {}
- set lt [expandAliases $t Tcl]
- switch -regexp -- $lt {
- {^\s*alias\s+.*} {
- message "alias to be added"
- if {[llength $lt] != 3} {
- set msg "Error: wrong number of arguments.\rForm is: alias <abrev> <replacement>"
- } else {
- catch {Shel::alias [lindex $lt 1] [lrange $lt 2 2]} msg
- }
-
- }
- default {
- if {[set code [catch {uplevel \#0 $lt} msg]] == 1} {
- # strip off end of error due to 'uplevel' command
- set new [split $errorInfo \n]
- set new [join [lrange $new 0 [expr [llength $new] - 4]] \n]
- set errorInfo "$new"
- set msg "Error: $msg"
- }
- }
- }
- set Shel::histnum [history nextid]
- return $msg
-
- }
-
- proc Alpha::Prompt {} {
- global Shel::startPrompt Shel::endPrompt
- return "${Shel::startPrompt}[file tail [string trimright [pwd] {:}]]${Shel::endPrompt} "
- }
-
- # ◊◊◊◊ MPW routines ◊◊◊◊ #
- namespace eval mpw {}
- proc mpw::evaluate {t} {
- catch {dosc -n ToolServer -s $t} r
- return $r
- }
- proc mpw::Prompt {} {
- global Shel::startPrompt Shel::endPrompt
- return "${Shel::startPrompt}mpw${Shel::endPrompt} "
- }
-
- proc toolserverShell {} {
- Shel::start "mpw" {*Toolserver shell*} \
- "Welcome to Alpha's MPW shell (using ToolServer via AppleEvents).\r"
- if {[catch {app::ensureRunning MPSX}]} {
- killWindow
- }
- }
-
- # ◊◊◊◊ Comet routines ◊◊◊◊ #
- namespace eval comet {}
- proc comet::evaluate {t} {
- cometSendAndPrompt $t
- return ""
- }
- proc comet::Prompt {} {}
-
- # ◊◊◊◊ General purpose ◊◊◊◊ #
-
- proc expandAliases {cmdLine {shellType Tcl}} {
- global Shel::AlphaAlias
- if {![info exists Shel::AlphaAlias]} {
- return $cmdLine
- }
- while {[string length $cmdLine]} {
- if {[regexp -indices -- \
- {([$]\{?|set\s+)?\b([a-zA-Z_][a-zA-Z_0-9]*)\b(([\.]|(::))[a-zA-Z_0-9]*)*} \
- $cmdLine all dc poss]} {
- if {$all != $poss} {
- set end [lindex $all 1]
- append rtnVal [string range $cmdLine 0 $end]
- set cmdLine [string range $cmdLine [incr end] end]
- } else {
- set start [lindex $poss 0]
- set end [lindex $poss 1]
- if {$start != 0} {
- append rtnVal [string range $cmdLine 0 [expr $start - 1]]
- }
- set possAlias [string range $cmdLine $start $end]
- if {[info exists Shel::AlphaAlias($possAlias)]} {
- append rtnVal [set Shel::AlphaAlias($possAlias)]
- } else {
- append rtnVal [string range $cmdLine $start $end]
- }
- set cmdLine [string range $cmdLine [incr end] end]
- }
- } else {
- append rtnVal $cmdLine
- break
- }
- }
- return $rtnVal
- }
-
- proc Shel::alias {abrev replacement} {
- global Shel::Type
- set fileName [win::CurrentTail]
- set type [set Shel::Type($fileName)]
-
- if {![regexp -- $abrev {[a-zA-Z_][a-zA-Z_0-9]*}]} {
- return "The name used for an alias must start with an alphabetic character \
- \nor an underscore, followed by zero or more characters of the same sort \
- \n(with numbers allowed also)."
- }
-
- if {"[info commands $abrev][procs::find $abrev]" != ""} {
- beep
- if {![string match [askyesno -c "'$abrev' is already a Tcl command, do you wish to Cancel?"] no ] } {
- return "No alias was formed"
- }
- }
-
- global Shel::${type}Alias
- if {[info exists Shel::${type}Alias($abrev)]} {
- beep
- if {![string match [askyesno -c "'$abrev' is already an alias for this shell, do you wish to Cancel?" ] no ] } {
- return "No alias was formed"
- }
- }
- mode::addUserLine [list set Shel::${type}Alias($abrev) $replacement]
- return "Saved alias in ShellPref.tcl file"
- }
-
- proc Shel::prevHist {} {
- global Shel::histnum Shel::curCmdLine Shel::endPrompt
-
- set text [getText [lineStart [getPos]] [nextLineStart [getPos]]]
- if {[set ind [string first "${Shel::endPrompt} " $text]] > 0} {
- goto [pos::math [lineStart [getPos]] + $ind + 2]
- } else return
-
- incr Shel::histnum -1
- if {[catch {history event ${Shel::histnum}} text]} {
- incr Shel::histnum
- endOfLine
- beep
- return
- }
- set to [nextLineStart [getPos]]
- if {[lookAt [pos::math $to -1]] == "\r"} {set to [pos::math $to -1]}
- if {[expr {${Shel::histnum} + 1}] == [history nextid] } {
- set Shel::curCmdLine [getText [getPos] $to]
- }
- replaceText [getPos] $to $text
- }
-
-
- proc Shel::nextHist {} {
- global Shel::histnum Shel::curCmdLine Shel::endPrompt
-
- set text [getText [lineStart [getPos]] [nextLineStart [getPos]]]
- if {[set ind [string first "${Shel::endPrompt} " $text]] > 0} {
- goto [pos::math [lineStart [getPos]] + $ind + 2]
- } else return
-
- if {${Shel::histnum} == [history nextid]} {
- beep
- endOfLine
- return
- }
-
- incr Shel::histnum
- if {${Shel::histnum} == [history nextid]} {
- set text ${Shel::curCmdLine}
- } else {
- if {[catch {history event ${Shel::histnum}} text]} {
- endOfLine
- return
- }
- }
- set to [nextLineStart [getPos]]
- if {[lookAt [pos::math $to - 1]] == "\r"} {set to [pos::math $to -1]}
- replaceText [getPos] $to $text
- }
-
- proc Shel::killLine {} {
- global Shel::endPrompt
- set text [getText [lineStart [getPos]] [nextLineStart [getPos]]]
- if {[set ind [string first "${Shel::endPrompt} " $text]] > 0} {
- goto [pos::math [lineStart [getPos]] + [expr {$ind + 2}]]
- } else {
- return
- }
- set to [nextLineStart [getPos]]
- if {[lookAt [pos::math $to - 1]] == "\r"} {set to [pos::math $to - 1]}
- deleteText [getPos] $to
- }
-
- proc Shel::Bol {} {
- global Shel::endPrompt
- set text [getText [lineStart [getPos]] [nextLineStart [getPos]]]
- if {[set ind [string first "${Shel::endPrompt} " $text]] > 0} {
- goto [pos::math [lineStart [getPos]] + [expr {$ind + 2}]]
- } else {
- goto [lineStart [getPos]]
- }
- }
-
- proc Shel::up {} {
- set pos [pos::math [lineStart [getPos]] - 1]
- if {[catch {regexp {∞} [getText [lineStart $pos] [nextLineStart $pos]]} res] || !$res} {
- previousLine; return
- }
- select [lineStart $pos] [nextLineStart $pos]
- }
-
- proc Shel::down {} {
- set pos [nextLineStart [getPos]]
- if {[catch {regexp {∞} [getText $pos [nextLineStart $pos]]} res] || !$res} {
- nextLine; return
- }
- select $pos [nextLineStart $pos]
- }
-
- # ◊◊◊◊ Unix imitation ◊◊◊◊ #
-
- proc l {args} {
- eval [concat "ls -CF" $args]
- }
-
- proc ll {args} {
- eval [concat "ls -l" $args]
- }
-
-
- proc wc {args} {
- set res {}
- set totChars 0
- set totLines 0
- set totWords 0
- set args [glob -nocomplain $args]
- foreach file $args {
- set id [open $file]
- set chars [string length [set text [read $id]]]
- set lines [llength [split $text "\n"]]
- set words [llength [split $text]]
- append res [format "\r%8d%8d%8d $file" $lines $words $chars]
- set totChars [expr $totChars+$chars]
- set totWords [expr $totWords+$words]
- set totLines [expr $totLines+$lines]
- close $id
- }
- if {[llength $args] > 1} {
- append res [format "\r%8d%8d%8d total" $totLines $totWords $totChars]
- }
- return [string range $res 1 end]
- }
-
-
-
- #================================================================================
- # To prevent ambiguity, 'from' is assumed to be a complete pathname, ending
- # in a directory name. If it doesn't end w/ a colon, one is added. 'to' is
- # assumed to be the parent directory of the top directory we are creating.
- #================================================================================
- proc cpdir {from to} {
- set cwd [pwd]
- if {[string match ":*" $from] || [string match ":*" $to] ||
- ![file exists $from] || ![file exists $to]} {
- error "'cpdir' args must be complete pathnames of existing folders."
- }
- if {![string match "*:" $from]} {append from ":"}
- if {![string match "*:" $to]} {append to ":"}
-
- if {![file isdir $from] || ![file isdir $to]} {
- exit 1
- }
-
- set res [catch {cphier $from $to} val]
- cd $cwd
- if {$res} {error $val}
- }
-
- proc cphier {from to} {
- set savedir [pwd]
- if {[string index $from [expr [string len $from] - 1]] != ":"} {append from ":"}
- set dir [file tail [string trimright $from ":"]]
- cd $to
- mkdir "$dir"
- foreach f [glob "$from*"] {
- if {[file isdir $f]} {
- cphier "$f:" "$to$dir:"
- } else {
- cp $f $to$dir:
- }
- }
- cd $savedir
- }
-
-
- #================================================================================
- #####
- # (Usage: 'lt' sorts by time, like UNIX's 'ls -lt'.
- # 'lt -t' sorts by filename, like UNIX's 'ls -l'.
- # Optionally a directory name can be added as an argument.)
-
- proc sortdt {dt} {
- scan $dt "%d/%d/%d {%d:%d:%d %1sM}" mon day yea hou min sec z
- if {$z == "P"} {incr hou 12}
- if {[string length $yea] == 1} {
- set year 200$yea
- } elseif {$yea > 40} {
- set year 19$yea
- } else {
- set year 20$yea
- }
- return [format "%04d%02d%02d%02d%02d" $year $mon $day $hou $min]
- }
-
-
- #===============================================================================
- #####
- # (Usage: 'lth' sorts by time, like UNIX's 'ls -lt'.
- # 'lth -t' sorts by filename, like UNIX's 'ls -l'.
- #
- # Optionally a filename path pattern can be added as an argument.
- # Examples:
- #
- # lth :Help:*
- # lth :Help:D*
- # lth HardDisk:news:*
- # lth HardDisk:news:R*
- # lth -t HardDisk:*
- #
- # are all good, if you have a volume named "HardDisk" and a
- # folder named "news" on it, but
- #
- # lth Help
- # lth :Help:
- #
- # are both bad.
- #
- # Use
- #
- # lth {"Macintosh Hd:*"}
- #
- # if you have spaces in the file or folder names.)
- #
- # This procedure is based only on the abbreviated format for dates and
- # time. It does not rely anymore on the short date format which avoids
- # problems such that 'Jan 2' giving either '1/2' (US) or '2/1' (UK).
- #
- # It assumes that :
- # 1. dates are coded as a four item list with a four digit field for years
- # and a two digit one for days (plus possible non-digit separators),
- # while weekdays and months are coded with characters in [\w] (plus
- # possible separators in [^\w]);
- # 2. day and month fields are consecutive ones and weekday field is before
- # them when the year field is either the first or the last one;
- # 3. time uses 'a' and 'p' in the strings coding twelve hour clocks (case
- # insensitive).
- #
- # This should cover most Mac OS formats for (north) America and Europe
- # ({weekday month day year} or {weekday day month year}), but not
- # non-latin encodings or slavic languages using (for month) characters
- # which are not in the default [\w] set.
- #
- # In (some) Mac OS, the Finnish abbreviated dates use up to six characters.
- # Allowing for month names with up to six characters gives an ugly and
- # confusing result for languages using three (or four) characters, thus
- # the procedure uses only 'ns' characters, where 'ns' is set to 4.
- #
-
- proc lth args {
- global mode
-
- set date [lindex [mtime [now] a] 0]
-
- #
- # Try to find the most likely format for dates.
- #
-
- set nmb [regexp "(\[0-9\]+)\[^0-9\]*(\[0-9\]+)" $date t one two]
- if {$nmb != 1} {
- error "Error while scanning the date stamp"
- }
- if {[string length $one] == 4} {
- set year $one
- set day $two
- } elseif {[string length $two] == 4} {
- set year $two
- set day $one
- } else {
- error "Error: cannot find the year"
- }
- set i 0
- set indd -1
- set indy -1
- foreach f $date {
- if {[regexp "\[0-9\]+" $f f]} {
- if {$f == $year} {set indy $i}
- if {$f == $day} {set indd $i}
- }
- incr i
- }
- if {($indy == 2) || ($indy == 3)} {
- if {$indd == [expr {$indy - 2}]} {
- set indm [expr {$indy - 1}]
- } elseif {$indd == [expr {$indy - 1}]} {
- set indm [expr {$indy - 2}]
- } else {
- error "Error: date format unknown"
- }
- } elseif {($indy == 0) || ($indy == 1)} {
- #
- # If your date format is {year month day weekday} or
- # {year day month weekday} uncomment the following 'if' 'elseif'
- # 'else' block and comment the next one.
- #
- # if {$indd == [expr {$indy + 2}]} {
- # set indm [expr {$indy + 1}]
- # } elseif {$indd == [expr {$indy + 1}]} {
- # set indm [expr {$indy + 2}]
- # } else {
- # error "Error: date format unknown"
- # }
- #
- if {$indd == 2} {
- set indm 3
- } elseif {$indd == 3} {
- set indm 2
- } else {
- error "Error: date format unknown"
- }
- } else {
- error "Error: date format unknown"
- }
-
- #
- # If you want to set manually the location of the different fields
- # comment (or remove) the lines between the comment
- # "Try to find the most likely format for dates." above and this block
- # and uncomment the following lines with 'yourXxxField' replaced
- # by a number between 0 and '[llength $date] - 1'.
- #
- # set indd yourDayField
- # set indm yourMonthField
- # set indy yourYearField
- # set year [lindex $date $indy]
- #
-
- set val "*"
- set sort 1
-
- foreach arg $args {
- switch -- $arg {
- "-t" {set sort 0}
- default {set val $arg}
- }
- }
-
- #
- # If you want the full Finnish abbreviated form, set 'ns' to 6;
- # if you want only three letters for the month, set 'ns' to 3.
- #
-
- set ns 4
- set nsp [expr {$ns + 1}]
- set nf [expr {$ns + 4}]
- set mod ""
- foreach f [eval glob $val] {
- if {[catch {getFileInfo $f info}]} {
- if {$sort} {set mod " "}
- lappend text [format "%s%s %8d%8d %${nf}s %5s %4s %s %s\n" \
- $mod "D" "0" "0" "" "" "" "DIR " [file tail $f]]
- continue
- }
- if {$sort} {set mod [format "%12u" $info(modified)]}
- set m [mtime $info(modified) a]
- set zer [lindex $m 0]
- regexp "(\[0-9\]+)" [lindex $zer $indd] day
- regexp "(\\w+)" [lindex $zer $indm] month
- set month [string range $month 0 [expr {$ns - 1}]]
- if {$indd < $indm} {
- for {set i [string length $month]} {$i < $ns} {incr i} {
- set month "$month "
- }
- set dat [format "%3s %${ns}s" $day $month]
- } else {
- set dat [format "%${nsp}s %2s" $month $day]
- }
- if {[lindex $zer $indy] == $year} {
- set time [lindex $m 1]
- set nmb [regexp "(\[0-9\]+)(\[^0-9\]+)(\[0-9\]+)" \
- $time t hour sep min]
- if {$nmb != 1} {
- error "Error while scanning the time stamp"
- }
- if {[regexp -nocase "p" $time] && ($hour < 12)} {
- set hour [expr $hour + 12]
- }
- if {[regexp -nocase "a" $time] && ($hour == 12)} {
- set hour [expr $hour - 12]
- }
- if {[string length $min] == 1} {set min "0$min"}
- set tm "$hour$sep$min"
- } else {
- regexp "(\[0-9\]+)" [lindex $zer $indy] yea
- set tm " $yea"
- }
- lappend text [format "%sF %8d%8d %${nf}s %5s %s %s %s\n" \
- $mod $info(datalen) $info(resourcelen) $dat $tm \
- $info(type) $info(creator) [file tail $f]]
- }
- if {$sort} {
- foreach ln [lsort -de $text] {
- append txt [string range $ln 12 end]
- }
- set ans [string trimright $txt]
- } else {
- set ans [string trimright [join $text {}]]
- }
-
- if { $mode=="Shel" } {
- return $ans
- } else {
- new
- insertText $ans "\r"
- catch shrinkHeight
- setWinInfo dirty 0
- setWinInfo read-only 1
- }
- }
-
-
- #================================================================================
- proc ps {} {
- foreach p [processes] {
- append text [format "%-25s %4s %10d %10d\r" [lindex $p 0] [lindex $p 1] [lindex $p 2] [lindex $p 3]]
- }
- return [string trimright $text]
- }
-
-
- #================================================================================
- # Recursively make creator of all text files 'ALFA'. Optionally takes a starting
- # dir argument, otherwise starts in current directory. Auto-Doubled are no
- # longer recognized by auto-doubler! Why? Some sort of conflict w/ 'PBSetFInfo'.
- proc creator {{dir ":"}} {
- if {![catch {glob -t TEXT $dir*} files]} {
- foreach f $files {
- message $f
- setFileInfo $f creator ALFA
- }
- }
-
- if {![catch {glob $dir*} dirs]} {
- foreach d $dirs {
- if {[file isdir $d]} {creator $d:}
- }
- }
- }
-
-
- #===============================================================================
-
- proc tomac args {
- set files {}
- foreach arg $args {
- eval lappend files [glob -nocomplain -- $arg]
- }
- set dir [pwd]
-
- foreach f $files {
- message "$f..."
- set fd [open [file join $dir $f] "r"]
- set text [read $fd]
- close $fd
- if {[info tclversion] < 8.0} {
- regsub -all "\n" $text "\r" text
- }
-
- set fd [open [file join $dir $f] "w"]
- puts -nonewline $fd $text
- close $fd
- }
- message ""
- }
-
-
- #===============================================================================
-
- proc unixToMac {fname} {
- set fd [open $fname]
- set text [read $fd]
- close $fd
- set fd [open $fname "w"]
- puts -nonewline $fd $text
- close $fd
- }
-
- proc setCreator {creator args} {
- set files {}
- foreach arg $args {
- eval lappend files [glob -nocomplain $arg]
- }
- foreach f $files {
- setFileInfo $f creator $creator
- }
- }
-
- proc setType {type args} {
- set files {}
- foreach arg $args {
- eval lappend files [glob -nocomplain $arg]
- }
- foreach f $files {
- setFileInfo $f type $type
- }
- }
- #===============================================================================
-
- proc pushd {args} {
- global otherDirs
- if {[string length $args]} {
- set otherDirs [cons [pwd] $otherDirs]
- cd [string trim [eval list $args] " \{\}"]
- } else {
- if {[llength $otherDirs]} {
- set n [car $otherDirs]
- set otherDirs [cons [pwd] [cdr $otherDirs]]
- cd $n
- } else {
- return "No other directories"
- }
- }
- }
- proc pd {args} {
- if {[string length $args]} {
- eval pushd $args
- } else {
- pushd
- }
- }
-
-
- proc dirs {} {global otherDirs; cons [pwd] $otherDirs}
-
- proc popd {} {
- global otherDirs
- if {[llength $otherDirs]} {
- cd [car $otherDirs]
- set otherDirs [cdr $otherDirs]
- } else {
- return "No other directories"
- }
- }
-
-